package com.sunthy.mall.service.admin.order;

import com.sunthy.mall.dao.admin.GoodsDao;
import com.sunthy.mall.dao.admin.OrderDao;
import com.sunthy.mall.dao.admin.ReplyDao;
import com.sunthy.mall.dao.admin.UserDao;
import com.sunthy.mall.dao.client.CommentsDao;
import com.sunthy.mall.model.admin.bo.client.order.*;
import com.sunthy.mall.model.admin.bo.order.OrderChangeBo;
import com.sunthy.mall.model.admin.bo.order.OrdersByPageBO;
import com.sunthy.mall.model.admin.pojo.admin.User;
import com.sunthy.mall.model.admin.pojo.client.Comments;
import com.sunthy.mall.model.admin.pojo.goods.Goods;
import com.sunthy.mall.model.admin.pojo.order.Orders;
import com.sunthy.mall.model.admin.pojo.goods.Spec;
import com.sunthy.mall.model.admin.pojo.reply.Reply;
import com.sunthy.mall.model.admin.vo.client.order.GoodsInnerOrder;
import com.sunthy.mall.model.admin.vo.client.order.OrderCarBo;
import com.sunthy.mall.model.admin.vo.order.OrderByIdInfoVo;
import com.sunthy.mall.model.admin.vo.order.OrderInnerSpecInfoId;
import com.sunthy.mall.model.admin.vo.order.OrdersByPageInnerOrderVO;
import com.sunthy.mall.model.admin.vo.order.OrdersByPageVO;
import com.sunthy.mall.utils.MyIPUtils;
import com.sunthy.mall.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;

import java.util.Date;
import java.util.ArrayList;
import java.util.List;

/**
 * 业务逻辑处理(实现类)
 */
public class OrderServiceImpl implements OrderService {

    //接下来需要做哪些事情？
    //1.查询当前条件下符合搜索条件的总记录数
    //2.当前页的具体条目信息
    // sqlSession.commit();  sqlSession.rollBack();
    @Override
    public OrdersByPageVO ordersByPage(OrdersByPageBO ordersByPageBO) {
        SqlSession sqlSession = MybatisUtils.openSession();
        OrderDao orderDao = sqlSession.getMapper(OrderDao.class);

        int count = orderDao.getTotalCount(ordersByPageBO);
        List<OrdersByPageInnerOrderVO> orders = orderDao.ordersByPage(ordersByPageBO);

        sqlSession.commit();
        sqlSession.close();

        OrdersByPageVO ordersByPageVO = new OrdersByPageVO();
        ordersByPageVO.setTotal(count);
        ordersByPageVO.setOrders(orders);

        return ordersByPageVO;
    }

    /********
     * 通过id在数据库中查找相应的数据封装成 Vo对象
     * @param id
     * @return orderByIdInfo（成功） null（失败）
     */
    @Override
    public OrderByIdInfoVo orderByIdInfo(int id) {
        OrderByIdInfoVo orderByIdInfoVo = null;
        SqlSession sqlSession = null;
        try {
            sqlSession = MybatisUtils.openSession();
            OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
            GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
            // 根据订单id 查找order
            Orders orders = orderDao.selOrderById(id);
            // 通过order的specId查找spec对象
            List<Spec> specList = goodsDao.SpecsByGoodsId(orders.getProductId());
            ArrayList<OrderInnerSpecInfoId> spec = new ArrayList<OrderInnerSpecInfoId>();
            for (Spec specs : specList) {
                OrderInnerSpecInfoId orderInnerSpecInfoId = new OrderInnerSpecInfoId(specs.getId(), specs.getName(), specs.getPrice());
                spec.add(orderInnerSpecInfoId);
            }
            // 创建orderByIdInfoVo
            orderByIdInfoVo = new OrderByIdInfoVo(orders.getId(), orders.getAmount(), orders.getNumber(), orders.getSpecId(), orders.getStateId(),
                    orders.getProduct(), spec, orders.getSpecId());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (sqlSession != null) {
                sqlSession.commit();
                sqlSession.close();
            }
        }
        return orderByIdInfoVo;
    }

    /***********
     * 将orderChangeBo解析
     * 订单id: 查找对应的order 获取product(goods) spec
     * 状态state:
     * 规格spec:
     * 数量num: 更改订单数量 以及创库数量(如果数量允许)
     * 更该相应数据
     * // 修改spec
     *       order
     *
     * @param orderChangeBo
     * @return 0(成功) 404 (数量不够) 500(异常)
     */
    @Override
    public int orderChange(OrderChangeBo orderChangeBo) {
//        Spec specBefore = null;
//        Spec specAfter = null;
//        SqlSession sqlSession = null;
//        try {
//            sqlSession = MybatisUtils.openSession();
//            OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
//            GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
//            // 查找对应id的order
//            Orders orders = orderDao.selOrderById(orderChangeBo.getId());
//            // spec的state只能变大
//            if (orderChangeBo.getSpec() < orders.getSpecId()) {
//                // 不能往回改
//                return 500;
//            }
//            // 获取对应productId的goods
//            Goods goods = goodsDao.getGoodsById(orders.getProductId());
//            // 获取对应goodsId的spec
//            List<Spec> specList = goodsDao.SpecsByGoodsId(goods.getId());
//
//
//            // 对数据进行判断
//            // 修改的商品数量是否充足
//            for (Spec spec : specList) {
//                if (spec.getId().equals(orders.getSpecId())) {
//                    specBefore = spec;
//                }
//                if (!(spec.getId().equals(orderChangeBo.getSpec()))) {
//                    continue;// 不是同一个规格的
//                }
//                if (spec.getStockNum() < orderChangeBo.getNum()) {// 是同规格的但是 对应数量不够 返回404
//                    return 404;
//                } else {
//                    // 同规格的spec  赋值
//                    specAfter = spec;//即将修改的spec (还未下单)
//                }
//            }
//            if (specBefore == null && specAfter == null) {
//                return 1000;
//            }
//            // 说明spec数量足够  修改两个spec的数量 spec(未下单)  order.getSpecId()
//            // 修改之前的(已经下单的)
//            specBefore.setStockNum(specBefore.getStockNum() + orders.getNumber());
//            goodsDao.updateSpec(specBefore);
//
//            // 修改之后的(还未下单的)
//            specAfter.setStockNum(specAfter.getStockNum() - orderChangeBo.getNum());
//            goodsDao.updateSpec(specAfter);
//
//            // 修改 order
//            orders.setStateId(orderChangeBo.getState());
//            orders.setSpecId(orderChangeBo.getSpec());
//
//            orders.setAmount(specAfter.getPrice() * orderChangeBo.getNum());
//
//            int change = orderDao.orderChange(orders);
//            if (change != 1) {
//                sqlSession.rollback();
//                sqlSession.close();
//                return 1000;
//            }
//        } catch (Exception e) {
//            if (sqlSession != null) {
//                sqlSession.rollback();
//                sqlSession.close();
//                return 1000;
//            }
//        }
//        if (sqlSession == null) {
//            return 1000;
//        }
//        sqlSession.commit();
//        sqlSession.close();
//        return 0;
//    }
//
//    public int orderChange1(OrderChangeBo orderChangeBo) {

        // 修改前的订单的规格
        Spec specBefore = null;
        // 修改后的订单规格
        Spec specAfter = null;

        // 获取会话
        SqlSession sqlSession = MybatisUtils.openSession();
        OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);

        // 根据订单id得到order
        Orders orders = orderDao.selOrderById(orderChangeBo.getId());

        // 判断更改前后的state 不能变小
        if (orderChangeBo.getState() < orders.getStateId()) {
            // 错误 不可向前更改
            // 关闭会话
            sqlSession.commit();
            sqlSession.close();
            return 100;
        }


        // 根据订单状态来分情况讨论
        // 0: spec, num, state
        // 1,2,3: state
        if (orders.getStateId() != 0) {
            // 只能修改state
            // 判断是否只有state变动
            if ((!orders.getSpecId().equals(orderChangeBo.getSpec())) || (!orders.getNumber().equals(orderChangeBo.getNum()))) {
                // 不相等 错误 只有未付款的订单可以修改规格
                // 关闭会话
                sqlSession.commit();
                sqlSession.close();
                return 200;
            }

            // 更改数据
            for (int i = 0; i < orderChangeBo.getState() - orders.getStateId(); i++) {
                int changeState = orderDao.changeOrderStateToPay(orderChangeBo.getId());
                if (changeState != 1) {
                    // 关闭会话
                    sqlSession.commit();
                    sqlSession.close();
                    // 更改数据异常
                    return 500;
                }
            }
            // 关闭会话
            sqlSession.commit();
            sqlSession.close();
            return 0;

        } else if (orders.getStateId() == 0) {

            // state=0 的情况 分析商品的规格 数量
            // 获取对应productId的goods
            Goods goods = goodsDao.getGoodsById(orders.getProductId());

            // 获取对应goodsId的spec
            List<Spec> specList = goodsDao.SpecsByGoodsId(goods.getId());

            // 比较specId 得到变化前后的spec
            for (Spec spec : specList) {
                if (spec.getId().equals(orders.getSpecId())) {
                    // 变化前
                    specBefore = spec;
                }
                if (spec.getId().equals(orderChangeBo.getSpec())) {
                    // 变化后
                    specAfter = spec;
                }
            }

            if (specAfter == null || specBefore == null) {
                // 关闭会话
                sqlSession.commit();
                sqlSession.close();
                return 500;
            }

            // 判断库存
            if (specAfter.getStockNum() < orderChangeBo.getNum()) {
                // 关闭会话
                sqlSession.commit();
                sqlSession.close();
                // 库存不够
                return 300;
            }

            // 修改数据
            int orderChange = orderDao.orderChange(
                    new Orders(
                            orderChangeBo.getId(),
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            null,
                            specAfter.getName(),
                            specAfter.getId(),
                            orderChangeBo.getNum(),
                            specAfter.getPrice() * orderChangeBo.getNum(),
                            orderChangeBo.getState(),
                            null));
            if (orderChange != 1) {
                // 关闭会话
                sqlSession.commit();
                sqlSession.close();
                return 500;
            }

            // 由未付款到付款需要将 库存的数量更改
            specAfter.setStockNum(specAfter.getStockNum() - orderChangeBo.getNum());
            goodsDao.updateSpec(specAfter);

            // 关闭会话
            sqlSession.commit();
            sqlSession.close();
            return 0;
        }
        // 关闭会话
        sqlSession.rollback();
        sqlSession.close();
        return 500;
    }

    /***********
     * 删除订单的业务逻辑
     *  1.根据id获取order
     *  2.判断order的状态码  （状态码为0时才可以删除）(都可)
     *  3.删除订单
     *  4.返回一个值0成功 500 失败
     * @param id
     * @return
     */
    @Override
    public int orderDeleteById(int id) {
        SqlSession sqlSession = MybatisUtils.openSession();
        OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
        // 获取order
        Orders order = orderDao.selOrderById(id);
        // 判状态码 todo
     /*   if (order.getStateId() != 0) {
            sqlSession.commit();
            sqlSession.close();
            // 失败
            return 500;
        }*/
        // 删除订单
        orderDao.deleteOrder(id);
        sqlSession.commit();
        sqlSession.close();
        // 成功
        return 0;
    }

    /**
     * 添加order
     *
     * @param addOrderBo
     * @return int
     */
    @Override
    public int addOrder(AddOrderBo addOrderBo) {
        // 获取会话
        SqlSession sqlSession = MybatisUtils.openSession();
        OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 添加order
        // 通过addOrderBo 获取order(email唯一)
        // 通过昵称获取user的信息
        List<User> userList = userDao.allUserByEmail(addOrderBo.getToken());
        if (userList.size() != 1) {
            // 异常
            return 500;
        }
        // 获取user
        User user = userList.get(0);
        // 获取商品信息de 规格
        Spec spec = goodsDao.selSpecById(addOrderBo.getGoodsDetailId());
        // 获取商品的信息
        Goods goods = goodsDao.getGoodsById(spec.getGoodsId());
        // 添加order
        Orders orders = new Orders(null, user.getId(), user.getNickname(), user.getRecipient(), user.getAddress(), user.getPhone(),
                goods.getName(), goods.getId(), spec.getName(), spec.getId(), addOrderBo.getNum(), addOrderBo.getAmount(),
                addOrderBo.getState(), 0);
        int addOrder = orderDao.addOrder(orders);
        // 关闭会话
        sqlSession.commit();
        sqlSession.close();
        // 返回结果
        if (addOrder == 1) {
            return 0;
        }
        return 500;
    }

    /**
     * 找到对应的state,token的order
     *
     * @param token
     * @param state
     * @return List<OrderCarBo>
     */
    @Override
    public List<OrderCarBo> getOrderByState(String token, Integer state) {
        // 获取会话
        SqlSession sqlSession = MybatisUtils.openSession();
        OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 根据state,token查找order
        // 根据token查找user
        List<User> userList = userDao.allUserByEmail(token);
        if (userList.size() != 1) {
            // 查找失败
            sqlSession.commit();
            sqlSession.close();
            return null;
        }
        User user = userList.get(0);
        // 根据userId , state 查找order 得到orderList
        List<Orders> ordersList = orderDao.selOrderByUserIdAndState(user.getId(), state);
        // 封装成List<OrderCarBo>
        List<OrderCarBo> orderCarBoList = new ArrayList<OrderCarBo>();
        for (Orders orders : ordersList) {
            // 遍历寻找order对应的goods和spec
            Spec spec = goodsDao.selSpecById(orders.getSpecId());
            // 查找goods
            Goods goods = goodsDao.getGoodsById(orders.getProductId());
            // 封装
            orderCarBoList.add(new OrderCarBo(
                    orders.getId(),
                    orders.getStateId(),
                    orders.getNumber(),
                    orders.getAmount(),
                    orders.getSpecId(),
                    orders.getCreatetime(),
                    orders.getHasComment(),
                    new GoodsInnerOrder(
                            spec.getGoodsId(),
                            MyIPUtils.getDomain()+goods.getImg(),
                            goods.getName(),
                            spec.getId(),
                            spec.getName(),
                            spec.getPrice()
                    )));
        }
        // 关闭会话
        sqlSession.commit();
        sqlSession.close();
        // 返回结果
        return orderCarBoList;
    }

    /**
     * 单支付订单
     *
     * @param id
     * @return int
     */
    @Override
    public int payOrderById(Integer id) {
        // 获取会话
        SqlSession sqlSession = MybatisUtils.openSession();
        OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
        // todo
        // 修改数据
        int pay = orderDao.changeOrderStateToPay(id);
        // 关闭会话
        sqlSession.commit();
        sqlSession.close();
        //返回结果
        if (pay != 1) {
            return 500;
        }
        return 0;
    }

    /**
     * 结算购物车
     *
     * @param carListBo
     * @return int
     */
    @Override
    public int settleAccountToCar(CarListBo carListBo) {
//        // 获取会话
//        SqlSession sqlSession = MybatisUtils.openSession();
//        OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
//        // 更改数据
//        for (CarList carList : carListBo.getCarList()) {
//            int pay  = orderDao.changeOrderStateToPay(carList.getId());
//            if (pay!=1){
//                return 500;
//            }
//        }
//        // 关闭会话
//        sqlSession.commit();
//        sqlSession.close();
//        // 返回结果
//        return 0;
//    }

        List<CarList> carList = carListBo.getCarList();
        for (CarList list : carList) {
            int pay = new OrderServiceImpl().payOrderById(list.getId());
            if (pay != 0) {
                return 500;
            }
        }
        return 0;
    }

    /**
     * 发送评论
     *
     * @param sendCommentBo
     * @return int
     */
    @Override
    public int sendComment(SendCommentBo sendCommentBo) {
        // 获取会话
        SqlSession sqlSession = MybatisUtils.openSession();
        CommentsDao commentsDao = sqlSession.getMapper(CommentsDao.class);
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        // 获取userId
        List<User> userList = userDao.allUserByEmail(sendCommentBo.getToken());
        if (userList.size() != 1) {
            sqlSession.commit();
            sqlSession.close();
            return 500;
        }
        User user = userList.get(0);
        // 获取specName
        Spec spec = goodsDao.selSpecById(sendCommentBo.getGoodsDetailId());
        // 修改数据库
        int code = commentsDao.addComments(
                new Comments(null,
                        sendCommentBo.getToken(),
                        sendCommentBo.getScore(),
                        spec.getName(),
                        sendCommentBo.getContent(),
                        new Date(),
                        user.getId(),
                        sendCommentBo.getGoodsId()));
        //关闭会话
        sqlSession.commit();
        sqlSession.close();
        // 返回结果
        if (code == 1) {
            return 0;
        }
        return 500;
    }


}
